package com.ljb.android.comm.mvp

import android.annotation.SuppressLint
import android.content.res.Configuration
import android.content.res.Resources
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.RelativeLayout
import androidx.annotation.ColorInt
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.viewbinding.ViewBinding
import com.gyf.immersionbar.ImmersionBar
import com.ljb.android.comm.R
import com.ljb.android.comm.databinding.CommLayoutLoadingDialogBinding
import com.ljb.android.comm.databinding.CommLayoutTitlebarBinding
import com.ljb.android.comm.weiget.page.PageState
import com.ljb.android.comm.weiget.page.PageStateLayout
import com.scwang.smart.refresh.footer.ClassicsFooter
import com.scwang.smart.refresh.header.MaterialHeader
import com.scwang.smart.refresh.layout.SmartRefreshLayout
import com.scwang.smart.refresh.layout.api.RefreshFooter
import com.scwang.smart.refresh.layout.api.RefreshHeader
import me.imid.swipebacklayout.lib.SwipeBackLayout
import me.imid.swipebacklayout.lib.app.SwipeBackActivityHelper
import mvp.ljb.kt.act.BaseMvpAppCompatActivity
import mvp.ljb.kt.contract.IPresenterContract
import org.greenrobot.eventbus.EventBus


/**
 * Author:Ljb
 * Time:2019/7/4
 * There is a lot of misery in life
 **/
abstract class CommMvpActivity<out P : IPresenterContract, B : ViewBinding> :
    BaseMvpAppCompatActivity<P>(), ICommView {

    /**
     * Root View
     * */
    protected lateinit var mRootView: ViewGroup

    /**
     * 内容 View
     * */
    private lateinit var mContentView: RelativeLayout

    /**
     * 拖拽\刷新 Layout
     * */
    private var mRefreshLayout: SmartRefreshLayout? = null

    /**
     * 左滑退出View
     * */
    private var mSwipeHelper: SwipeBackActivityHelper? = null
    private var isSwiping = false


    /**
     * Title布局 ViewBind
     * @需要: supportTitle() return true
     * */
    protected lateinit var mBindTitleBar: CommLayoutTitlebarBinding

    /**
     * Loading布局 ViewBind
     * */
    protected lateinit var mBindLoading: CommLayoutLoadingDialogBinding

    /**
     * 业务布局 ViewBind
     * */
    protected lateinit var mBind: B

    abstract fun registerBinding(layoutInflater: LayoutInflater, parent: ViewGroup): B

    override fun onCreate(savedInstanceState: Bundle?) {
        initStatusBar()
        super.onCreate(savedInstanceState)
        initOther()
    }

    override fun initContentView() {

        // contentView
        mContentView = RelativeLayout(this).apply {
            layoutParams = ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT
            )
            setBackgroundResource(R.color.bg_page)
        }

        // content view
        mBind = registerBinding(layoutInflater, mContentView)

        // title view
        if (supportTitle()) {
            initTitleBar(layoutInflater)
        }

        // 上下拖拽 Layout
        if (supportDraw() || supportRefresh() || supportLoadMore()) {
            initDrawLayout()
        } else {
            initCenterView()
        }

        // loading view
        initLoadingView(layoutInflater)

        // rootView
        mRootView = if (supportPage()) {
            PageStateLayout(this, customPageTag())
                .apply {
                    setContentView(mContentView)
                    setRetryPageListener { onPageRetry() }
                }
        } else {
            mContentView
        }

        setContentView(mRootView)
    }


    private fun initDrawLayout() {
        // 拖拽Layout
        mRefreshLayout = SmartRefreshLayout(this)
        val refreshLayoutParams = RelativeLayout.LayoutParams(
            RelativeLayout.LayoutParams.MATCH_PARENT,
            RelativeLayout.LayoutParams.WRAP_CONTENT
        )
        if (supportTitle()) {
            refreshLayoutParams.addRule(RelativeLayout.BELOW, mBindTitleBar.root.id)
        }

        // 开发要展示的内容
        val centerLayoutParams = SmartRefreshLayout.LayoutParams(
            SmartRefreshLayout.LayoutParams.MATCH_PARENT,
            SmartRefreshLayout.LayoutParams.WRAP_CONTENT
        )
        mRefreshLayout?.addView(mBind.root, centerLayoutParams)

        // 添加到页面上
        mContentView.addView(mRefreshLayout, refreshLayoutParams)

        // 开启上下拖拽功能
        setEnableRefresh(supportDraw())
        setEnableLoadMore(supportDraw())

        // 添加刷新Header
        if (supportRefresh()) {
            mRefreshLayout?.apply {
                setRefreshHeader(customRefreshHeader())
                setEnableHeaderTranslationContent(true)
                setEnableRefresh(true)
                setOnRefreshListener { onRefresh() }
            }
        }

        // 添加加载Footer
        if (supportLoadMore()) {
            mRefreshLayout?.apply {
                setRefreshFooter(customRefreshFooter())
                setEnableLoadMore(true)
                setOnLoadMoreListener { onLoadMore() }
            }
        }
    }

    private fun initCenterView() {
        // 开发要展示的内容
        val layoutParams = RelativeLayout.LayoutParams(
            RelativeLayout.LayoutParams.MATCH_PARENT,
            RelativeLayout.LayoutParams.MATCH_PARENT
        )
        if (supportTitle()) {
            layoutParams.addRule(RelativeLayout.BELOW, mBindTitleBar.root.id)
        }
        mContentView.addView(mBind.root, layoutParams)
    }

    private fun initLoadingView(inflater: LayoutInflater) {
        mBindLoading = CommLayoutLoadingDialogBinding.inflate(inflater, mContentView, false)
        mContentView.addView(mBindLoading.root)
    }

    private fun initTitleBar(inflater: LayoutInflater) {
        mBindTitleBar = CommLayoutTitlebarBinding.inflate(inflater, mContentView, false)
        mBindTitleBar.ivToolbarLeft.setOnClickListener { onBackPressed() }
        mContentView.addView(mBindTitleBar.root)
    }

    @SuppressLint("MissingSuperCall")
    override fun onDestroy() {
        super.onDestroy()
        unOther()
    }

    private fun initOther() {
        initEventBus()
        initSwipe()
    }

    private fun unOther() {
        unEventBus()
    }

    private fun initSwipe() {
        if (supportSwipeBack()) {
//            XLog.d(javaClass.simpleName + "::支持 Swipe")
            mSwipeHelper = SwipeBackActivityHelper(this)
                .apply {
                    onActivityCreate()
                    swipeBackLayout.apply {
                        //设置滑动敏感度
                        setSensitivity(this@CommMvpActivity, 0.2f)
                        //设置全屏滑动
                        setEdgeTrackingEnabled(SwipeBackLayout.EDGE_LEFT)
                        setShadow(
                            R.drawable.comm_swipe_back,
                            SwipeBackLayout.EDGE_LEFT
                        )
                        //设置监听
                        addSwipeListener(object : SwipeBackLayout.SwipeListener {

                            override fun onScrollStateChange(state: Int, scrollPercent: Float) {
                                //滑动结束
                                if (state == 0) {
                                    isSwiping = false
                                }
                            }

                            override fun onScrollOverThreshold() {
                                //滑动开始
                                isSwiping = true
                                hideSoftInputFromWindow()
                            }

                            override fun onEdgeTouch(edgeFlag: Int) {}
                        })
                    }
                }
        }
    }

    override fun onPostCreate(savedInstanceState: Bundle?) {
        super.onPostCreate(savedInstanceState)
        if (supportSwipeBack()) {
            mSwipeHelper?.onPostCreate()
        }
    }

    private fun initEventBus() {
        if (supportEventBus() && !EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this)
        }
    }

    private fun unEventBus() {
        if (supportEventBus() && EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this)
        }
    }

    private fun setLoading(isShow: Boolean) {
        mBindLoading.root.visibility = if (isShow) View.VISIBLE else View.GONE
    }

    override fun showLoading() {
        setLoading(true)
    }

    override fun hideLoading() {
        setLoading(false)
    }

    protected fun setTitleText(
        @StringRes resId: Int,
        @ColorInt colorId: Int = resources.getColor(R.color.color_333)
    ) {
        if (supportTitle()) {
            mBindTitleBar.tvToolbarCenter.setText(resId)
            mBindTitleBar.tvToolbarCenter.setTextColor(colorId)
        }
    }

    protected fun setTitleText(
        text: String,
        @ColorInt colorId: Int = resources.getColor(R.color.color_333)
    ) {
        if (supportTitle()) {
            mBindTitleBar.tvToolbarCenter.text = text
            mBindTitleBar.tvToolbarCenter.setTextColor(colorId)
        }
    }

    protected fun setTitleLeftImage(@DrawableRes resId: Int) {
        if (supportTitle()) {
            mBindTitleBar.ivToolbarLeft.setImageResource(resId)
        }
    }

    protected fun setTitleLeftImage(@DrawableRes resId: Int, listener: View.OnClickListener) {
        if (supportTitle()) {
            mBindTitleBar.ivToolbarLeft.setImageResource(resId)
            mBindTitleBar.ivToolbarLeft.setOnClickListener(listener)
        }
    }

    protected fun setTitleRightImage(@DrawableRes resId: Int, listener: View.OnClickListener) {
        if (supportTitle()) {
            mBindTitleBar.ivToolbarRight.setImageResource(resId)
            mBindTitleBar.ivToolbarRight.setOnClickListener(listener)
            if (View.VISIBLE != mBindTitleBar.ivToolbarRight.visibility) {
                mBindTitleBar.ivToolbarRight.visibility = View.VISIBLE
            }
        }
    }

    protected fun setTitleRightText(@StringRes resId: Int, listener: View.OnClickListener) {
        setTitleRightText(getText(resId), listener)
    }

    protected fun setTitleRightText(text: CharSequence, listener: View.OnClickListener) {
        if (supportTitle()) {
            mBindTitleBar.tvToolbarRight.text = text
            mBindTitleBar.tvToolbarRight.setOnClickListener(listener)
            if (View.VISIBLE != mBindTitleBar.tvToolbarRight.visibility) {
                mBindTitleBar.tvToolbarRight.visibility = View.VISIBLE
            }
        }
    }


    protected open fun initStatusBar() {
        ImmersionBar.with(this)
            .transparentStatusBar()     //透明状态栏，不写默认透明色
            .statusBarDarkFont(true) //状态栏字体是深色，不写默认为亮色
            .navigationBarDarkIcon(true) //导航栏图标是深色，不写默认为亮色
            .init()
//            .transparentStatusBar() //透明状态栏，不写默认透明色
//            .transparentNavigationBar() //透明导航栏，不写默认黑色(设置此方法，fullScreen()方法自动为true)
//            .transparentBar() //透明状态栏和导航栏，不写默认状态栏为透明色，导航栏为黑色（设置此方法，fullScreen()方法自动为true）
//            .statusBarColor(android.R.color.transparent) //状态栏颜色，不写默认透明色
//            .navigationBarColor(android.R.color.black) //导航栏颜色，不写默认黑色
//            .barColor(android.R.color.black) //同时自定义状态栏和导航栏颜色，不写默认状态栏为透明色，导航栏为黑色
//            .statusBarAlpha(0.3f) //状态栏透明度，不写默认0.0f
//            .navigationBarAlpha(0.4f) //导航栏透明度，不写默认0.0F
//            .barAlpha(0.3f) //状态栏和导航栏透明度，不写默认0.0f
//            .statusBarDarkFont(true) //状态栏字体是深色，不写默认为亮色
//            .navigationBarDarkIcon(true) //导航栏图标是深色，不写默认为亮色
//            .autoDarkModeEnable(true) //自动状态栏字体和导航栏图标变色，必须指定状态栏颜色和导航栏颜色才可以自动变色哦
//            .autoStatusBarDarkModeEnable(true, 0.2f) //自动状态栏字体变色，必须指定状态栏颜色才可以自动变色哦
//            .autoNavigationBarDarkModeEnable(true, 0.2f) //自动导航栏图标变色，必须指定导航栏颜色才可以自动变色哦
//            .flymeOSStatusBarFontColor(android.R.color.black) //修改flyme OS状态栏字体颜色
//            .fullScreen(true) //有导航栏的情况下，activity全屏显示，也就是activity最下面被导航栏覆盖，不写默认非全屏
//            .hideBar(BarHide.FLAG_HIDE_BAR) //隐藏状态栏或导航栏或两者，不写默认不隐藏
//            .addViewSupportTransformColor(titleView) //设置支持view变色，可以添加多个view，不指定颜色，默认和状态栏同色，还有两个重载方法
//            .titleBar(titleView) //解决状态栏和布局重叠问题，任选其一
//            .titleBarMarginTop(titleView) //解决状态栏和布局重叠问题，任选其一
//            .statusBarView(titleView) //解决状态栏和布局重叠问题，任选其一
//            .fitsSystemWindows(true) //解决状态栏和布局重叠问题，任选其一，默认为false，当为true时一定要指定statusBarColor()，不然状态栏为透明色，还有一些重载方法
//            .supportActionBar(true) //支持ActionBar使用
//            .statusBarColorTransform(android.R.color.black) //状态栏变色后的颜色
//            .navigationBarColorTransform(android.R.color.black) //导航栏变色后的颜色
//            .barColorTransform(android.R.color.black) //状态栏和导航栏变色后的颜色
//            .removeSupportView(titleView) //移除指定view支持
//            .removeSupportAllView() //移除全部view支持
//            .navigationBarEnable(true) //是否可以修改导航栏颜色，默认为true
//            .navigationBarWithKitkatEnable(true) //是否可以修改安卓4.4和emui3.x手机导航栏颜色，默认为true
//            .navigationBarWithEMUI3Enable(true) //是否可以修改emui3.x手机导航栏颜色，默认为true
//            .keyboardEnable(true) //解决软键盘与底部输入框冲突问题，默认为false，还有一个重载方法，可以指定软键盘mode
//            .keyboardMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) //单独指定软键盘模式
//            .setOnKeyboardListener(OnKeyboardListener { isPopup, keyboardHeight ->
//                //软键盘监听回调，keyboardEnable为true才会回调此方法
//                //isPopup为true，软键盘弹出，为false，软键盘关闭
//            })
//            .setOnNavigationBarListener(onNavigationBarListener) //导航栏显示隐藏监听，目前只支持华为和小米手机
//            .setOnBarListener(OnBarChangeListener) //第一次调用和横竖屏切换都会触发，可以用来做刘海屏遮挡布局控件的问题
//            .addTag("tag") //给以上设置的参数打标记
//            .getTag("tag") //根据tag获得沉浸式参数
//            .reset() //重置所以沉浸式参数
//            .init() //必须调用方可应用以上所配置的参数
    }

    override fun getResources(): Resources {
        val res = super.getResources()
        val newConfig = Configuration()
        newConfig.setToDefaults()
        res.updateConfiguration(newConfig, res.displayMetrics)
        return res
    }

    //显示软件盘
    protected open fun openSoftInputFromWindow() {
        val im = getSystemService(INPUT_METHOD_SERVICE)
        val currentView = currentFocus
        if (im != null && currentView != null && im is InputMethodManager) {
            val iBinder = currentFocus!!.applicationWindowToken
            im.showSoftInput(currentView, InputMethodManager.SHOW_FORCED)
            im.hideSoftInputFromWindow(
                iBinder,
                InputMethodManager.HIDE_NOT_ALWAYS
            )
        }
    }

    //隐藏软键盘
    protected open fun hideSoftInputFromWindow() {
        val im = getSystemService(INPUT_METHOD_SERVICE)
        val currentView = currentFocus
        if (im != null && currentView != null && im is InputMethodManager) {
            val iBinder = currentFocus!!.applicationWindowToken
            im.hideSoftInputFromWindow(
                iBinder,
                InputMethodManager.HIDE_NOT_ALWAYS
            )
        }
    }

    override fun onBackPressed() {
        if (supportSwipeBack() && isSwiping) return
        super.onBackPressed()
    }


    /**
     * 开发人员可以重写 -> 自定义加载更多
     * */
    private fun customRefreshFooter(): RefreshFooter {
        return ClassicsFooter(this).apply {
            setBackgroundResource(R.color.bg_page)
        }
    }

    /**
     * 加载更多开关
     * */
    protected fun setEnableLoadMore(enable: Boolean) {
        mRefreshLayout?.setEnableLoadMore(enable)
    }

    /**
     * 加载更多结束
     * */
    protected fun finishLoadMore(success: Boolean = true) {
        mRefreshLayout?.finishLoadMore(success)
    }

    /**
     * 加载更多结束
     * */
    protected fun setNoLoadMore(noMore: Boolean = true) {
        mRefreshLayout?.setNoMoreData(noMore)
    }

    /**
     * 下拉刷新回調
     * 仅在 supportRefresh() 返回true时，才会被执行
     * */
    protected open fun onLoadMore() {

    }

    /**
     * 开发人员可以重写 -> 自定义刷新头
     * */
    protected open fun customRefreshHeader(): RefreshHeader {
        return MaterialHeader(this).apply {
            setColorSchemeResources(
                R.color.color_39B6DF,
                R.color.color_1296DB,
                R.color.color_6385F8
            )
        }
    }

    /**
     * 刷新开关
     * */
    protected fun setEnableRefresh(enable: Boolean) {
        mRefreshLayout?.setEnableRefresh(enable)
    }

    /**
     * 刷新结束
     * */
    protected fun finishRefresh(success: Boolean = true) {
        mRefreshLayout?.finishRefresh(success)
    }

    /**
     * 仅播放刷新动画，不回调onRefresh
     * */
    protected fun autoRefreshAnimationOnly() {
        mRefreshLayout?.autoRefreshAnimationOnly()
    }

    /**
     * 触发刷新，并播放动画
     * */
    protected fun autoRefresh() {
        mRefreshLayout?.autoRefresh()
    }

    /**
     * 下拉刷新回調
     * 仅在 supportRefresh() 返回true时，才会被执行
     * */
    protected open fun onRefresh() {

    }

    /**
     * 页面出错重试
     * 默认执行  onRefresh() 或者 initData()
     * 开发人员可根据实际情况覆写该方法
     * */
    protected open fun onPageRetry() {
        if (supportRefresh()) {
            setPage(PageState.STATE_LOADING)
            onRefresh()
        } else {
            initData()
        }
    }

    /**
     * 自定义使用哪套Page页面
     * */
    protected open fun customPageTag(): String {
        return PageStateLayout.TAG_DEFAULT
    }

    /**
     * 切换页面状态
     * */
    protected fun setPage(page: PageState) {
        if (supportPage() && mRootView is PageStateLayout) {
            (mRootView as PageStateLayout).setPage(page)
        }
    }

    /**
     * 设置内容的背景色
     * */
    protected fun setBackgroundColor(@ColorInt colorId: Int) {
        mContentView.setBackgroundColor(colorId)
    }

    /**
     * 是否支持 EventBus
     * @return true(支持)  false(不支持)
     * */
    protected open fun supportEventBus() = false

    /**
     * 是否显示 TitleBar
     * @return true(显示)  false(不显示)
     * */
    protected open fun supportTitle() = false

    /**
     * 是否支持上下拖拽 Layout
     * @return true(支持)  false(不支持)
     * */
    protected open fun supportDraw() = false

    /**
     * 是否支持左右拖拽退出
     * @return true(支持)  false(不支持)
     * */
    protected open fun supportSwipeBack() = false

    /**
     * 是否支持下拉刷新
     * @return true(支持)  false(不支持)
     * */
    protected open fun supportRefresh() = false

    /**
     * 是否支持加载更多
     * @return true(支持)  false(不支持)
     * */
    protected open fun supportLoadMore() = false

    /**
     * 是否支持页面状态切换
     * @return true(支持)  false(不支持)
     * */
    protected open fun supportPage() = false

}